
package cz.czu.pef.DataModelling.entityObjects;

import java.util.*;

import javax.persistence.*;

import org.hibernate.annotations.Index;

/**
 * This entity represents Company with its relations to addresses, employees, external workers and machineries.
 * 
 * @author rstribrn
 *
 */
@Entity
@Table(name="COMPANY")
@Inheritance(strategy=InheritanceType.JOINED)
@NamedQueries({
	@NamedQuery(name="findCompanyByName", query="SELECT c FROM CompanyEntityImpl c WHERE c.name = :name"),
	@NamedQuery(name="findCompanyByIco", query="SELECT c FROM CompanyEntityImpl c WHERE c.ico = :ico")
})
public class CompanyEntityImpl extends IdPersistenceEntityObjectImpl implements IdPersistenceEntityObject
{
	private static final long serialVersionUID = -3846628860514746169L;

	/*
	 * Entity attributes
	 */
	@Column(name="COMPANY_NAME", nullable=false, length=200)
	@Index(name="IDX_COMPANY_NAME")
	private String name;

	@Column(name="COMPANY_ICO", nullable=false, length=32)
	@Index(name="IDX_COMPANY_ICO")
	private String ico;

	@Column(name="COMPANY_DIC", nullable=true, length=32)
	@Index(name="IDX_COMPANY_DIC")
	private String dic;

	@ManyToOne(fetch=FetchType.EAGER, targetEntity=AddressEntityImpl.class) // no cascade
	private AddressEntityImpl baseAddress;

	@ManyToMany(fetch=FetchType.EAGER, targetEntity=AddressEntityImpl.class) // no cascade
	@JoinTable(name="BRANCH_COMPANY_ADDRESSES")
	private Set<AddressEntityImpl> branchAddresses;

	/*
	 * Relations
	 */
	@ManyToMany(fetch=FetchType.EAGER, targetEntity=EmployeeEntityImpl.class) // no cascade
	@JoinTable(name="COMPANY_EMPLOYEES")
	private Set<EmployeeEntityImpl> employees;

	@ManyToMany(fetch=FetchType.EAGER, targetEntity=ExternalWorkerEntityImpl.class) // no cascade
	@JoinTable(name="COMPANY_EXTERNAL_WORKERS")
	private Set<ExternalWorkerEntityImpl> extWorkers;

	@OneToMany(fetch=FetchType.EAGER, targetEntity=MachineryEntityImpl.class, mappedBy="companyOwner") // no cascade
	private Set<MachineryEntityImpl> machinery;

	public CompanyEntityImpl()
	{
		super();
	}

	public CompanyEntityImpl(final String name, final String ico, final String dic)
	{
		setName(name);
		setIco(ico);
		setDic(dic);
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getIco()
	{
		return ico;
	}

	public void setIco(String ico)
	{
		this.ico = ico;
	}

	public String getDic()
	{
		return dic;
	}

	public void setDic(String dic)
	{
		this.dic = dic;
	}
	
	public AddressEntityImpl getBaseAddress()
	{
		return baseAddress;
	}

	public void setBaseAddress(AddressEntityImpl baseAddress)
	{
		this.baseAddress = baseAddress;
	}

	public Set<AddressEntityImpl> getBranchAddresses()
	{
		return branchAddresses;
	}

	public List<AddressEntityImpl> getBranchAddressesAsList()
	{
		return new ArrayList<AddressEntityImpl>(getBranchAddresses());
	}

	public void addBranchAddress(AddressEntityImpl address)
	{
		if (branchAddresses == null)
			branchAddresses = new HashSet<AddressEntityImpl>();
		branchAddresses.add(address);
	}

	public void hireEmployee(EmployeeEntityImpl employee)
	{
		if (employees == null)
			employees = new HashSet<EmployeeEntityImpl>();
		employees.add(employee);
	}

	public void hireExternalWorker(ExternalWorkerEntityImpl employee)
	{
		if (extWorkers == null)
			extWorkers = new HashSet<ExternalWorkerEntityImpl>();
		extWorkers.add(employee);
	}

	public Set<EmployeeEntityImpl> getEmployees()
	{
		return employees;
	}

	public List<EmployeeEntityImpl> getEmployeesAsList()
	{
		return new ArrayList<EmployeeEntityImpl>(getEmployees());
	}

	public Set<ExternalWorkerEntityImpl> getExtWorkers()
	{
		return extWorkers;
	}

	public List<ExternalWorkerEntityImpl> getExtWorkersAsList()
	{
		return new ArrayList<ExternalWorkerEntityImpl>(getExtWorkers());
	}

	public Set<MachineryEntityImpl> getMachinery()
	{
		return machinery;
	}

	public List<MachineryEntityImpl> getMachineryAsList()
	{
		return new ArrayList<MachineryEntityImpl>(getMachinery());
	}

    
  public void setBranchAddresses(Set<AddressEntityImpl> branchAddresses)
  {
    this.branchAddresses = branchAddresses;
  }

  
  public void setEmployees(Set<EmployeeEntityImpl> employees)
  {
    this.employees = employees;
  }

  
  public void setExtWorkers(Set<ExternalWorkerEntityImpl> extWorkers)
  {
    this.extWorkers = extWorkers;
  }

    @Override
	public String toString()
	{
		StringBuilder builder = new StringBuilder();
		builder.append("Company [name=");
		builder.append(getName());
		builder.append(", ico=");
		builder.append(getIco());
		builder.append(", baseAddress=");
		builder.append(getBaseAddress());
		builder.append(", branchAddresses=");
		builder.append(getBranchAddresses());
		builder.append(", employees=");
		builder.append(getEmployees());
		builder.append(", extWorkers=");
		builder.append(getExtWorkers());
		builder.append(", machinery=");
		builder.append(getMachinery());
		builder.append(", toString()=");
		builder.append(super.toString());
		builder.append("]");
		return builder.toString();
	}

	/* (non-Javadoc)
	 * @see cz.czu.pef.DataModelling.domainObjects.Company#canBeRemoved()
	 */
	@Override
	public boolean canBeRemoved()
	{
		return getMachinery().size() == 0; 
	}

}
